package me.fung.rem.app.content

import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import com.alibaba.excel.EasyExcel
import com.alibaba.excel.read.listener.PageReadListener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import me.fung.keen.app.view.Presenter
import me.fung.keen.common.TextClipboard
import me.fung.keen.component.message.msg
import me.fung.rem.app.encryptor
import me.fung.rem.app.main.FILE
import me.fung.rem.bean.database
import me.fung.rem.bean.repo.*
import me.fung.rem.component.swing.chooseFile
import mu.KotlinLogging
import org.ktorm.dsl.*
import org.ktorm.entity.*
import java.io.File
import java.nio.file.FileSystems
import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.util.*
import kotlin.collections.ArrayList

class ContentPresenter : Presenter() {
    private val logger = KotlinLogging.logger { }
    val list = mutableStateListOf<RemItem>()
    val filter = mutableStateOf("")
    var newFilter = false
    val filterList = mutableStateListOf<String>()

    private var loadJob: Job? = null
    fun load() {
        loadJob?.cancel()
        loadJob = null
        loadJob = CoroutineScope(Dispatchers.IO).launch {
            val encryptor = encryptor()
            val resultList = ArrayList<RemItem>()
            val itemList = database.remItems.filter {
                it.del eq false
            }
            itemList.map { it.copy(password = encryptor.decrypt(it.password)) }.also { resultList.addAll(it) }
            val fl = filterList.toMutableList()
            if (filter.value != "") {
                fl.add(filter.value)
            }
            val iterator = resultList.iterator()
            while (iterator.hasNext()) {
                run fForEach@{
                    val item = iterator.next()
                    fl.forEach { f ->
                        if (
                            !item.title.contains(f, true) &&
                            !item.username.contains(f, true) &&
                            !item.info.contains(f, true) &&
                            !item.address.contains(f, true) &&
                            !item.tag.contains(f, true)
                        ) {
                            iterator.remove()
                            return@fForEach
                        }
                    }
                }
            }
            list.clear()
            list.addAll(resultList)
        }
    }

    fun addSearch(content: String) {
        if (content.trim() == "") return
        val s = Search(content.trim(), LocalDateTime.now())
        database.searches.add(s)
    }

    fun deleteSearch() {
        database.delete(Searches) {
            it.time lt LocalDateTime.now().minusDays(configSearchDays.toLong())
        }
    }

    var search = mutableStateListOf<String>()
    fun showSearch() {
        val l = database.searches.groupBy {
            it.content
        }.map { it ->
            it.key to it.value.size
        }.sortedByDescending { it.second } //.subList(0, 2).map { it.first }
        val l1 = if (l.size > 5) l.subList(0, 5) else l
        val r = l1.map { it.first }
        search.clear()
        search.addAll(r)
    }

    // 保存搜索框中的搜索条件,然后刷新显示
    fun saveFilterSearch() {
        if (!newFilter) return
        addSearch(filter.value)
        newFilter = false
        showSearch()
    }

    fun addFilter(f: String) {
        filterList.add(f)
    }

    fun removeFilter(f: String) {
        filterList.remove(f)
    }

    private var writeJob: Job? = null
    fun write() {
        if (writeJob != null) return
        writeJob = CoroutineScope(Dispatchers.IO).launch {
            try {
                val fileName: String =
                    FILE + File.separator + SimpleDateFormat("yyyyMMddHHmmss").format(Date()) + ".xlsx"
                EasyExcel.write(fileName, RemItem::class.java)
                    .sheet("模板")
                    .doWrite(list)
                val f = System.getProperty("user.dir") + FileSystems.getDefault().separator + FILE
                val info = "导出成功（${fileName}），已复制到剪贴板(${f}）。"
                TextClipboard.copy(f)
                msg.send { info(info) }
                logger.info { info }
            } finally {
                writeJob = null
            }
        }
    }

    private var readJob: Job? = null
    fun read() {
        if (readJob != null) return
        readJob = CoroutineScope(Dispatchers.IO).launch {
            try {
                val fileName = chooseFile() ?: return@launch
                EasyExcel.read(fileName,
                    RemItem::class.java, PageReadListener { dataList: List<RemItem> ->
                        for (data in dataList) {
                            data.add()
                        }
                    }
                ).sheet().doRead()
                load()
                val info = "导入成功:$fileName"
                msg.send { info(info) }
                logger.info { info }
            } finally {
                readJob = null
            }
        }
    }

}